package com.whalefin.controller.file;

import com.whalefin.service.tools.ApplicationParams;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by ruihuang on 14-4-28.
 */
@Controller
public class FileController {

	Logger log = LoggerFactory.getLogger(FileController.class);

	@RequestMapping(method = RequestMethod.GET, value = "/imgFile")
	public byte[] getFile(String fileName, HttpServletResponse response) {
		try {
			// get your file as InputStream
			InputStream is = new FileInputStream(
					new File(genFilePath(fileName)));
			// copy it to response's OutputStream
			scaleByWidth(is, response.getOutputStream(), 640);
		} catch (IOException ex) {
			log.warn(ex.getMessage());
		}
		return null;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/uploadImg")
	public @ResponseBody Map<String, Object> postFile(
			@RequestParam Map<String, String> params,
			@RequestParam("imgFile") MultipartFile file) throws IOException {

		Map<String, Object> result = new HashMap<String, Object>();

		// 转存上传文件
		// 如果文件不为空，并且类型为image
		if (file.getSize() > 0
				&& StringUtils.equals(params.get("dir"), "image")) {
			String fileName = genFileName(file);
			FileCopyUtils
					.copy(file.getBytes(), new File(genFilePath(fileName)));
			result.put("error", 0);
			result.put("url", "/imgFile?fileName=" + fileName);
		} else {
			result.put("error", 1);
			result.put("url", "请上传图片类型文件!");
		}

		return result;
	}

	private String genFilePath(String fileName) {
		return ApplicationParams.IMG_SAVE_FOLDER + fileName;
	}

	private String genFileName(MultipartFile file) {
		// 使用时间做文件的prefix，防止文件冲突;
		String prefix = String.valueOf(new Date().getTime());
		return prefix + "-" + file.getOriginalFilename();
	}

	private Dimension getScaledDimension(Dimension imgSize, int maxWidth) {

		int original_width = imgSize.width;
		int original_height = imgSize.height;
		int bound_width = maxWidth;
		int new_width = original_width;
		int new_height = original_height;

		// first check if we need to scale width
		if (original_width > bound_width) {
			// scale width to fit
			new_width = bound_width;
			// scale height to maintain aspect ratio
			new_height = (new_width * original_height) / original_width;
		}

		return new Dimension(new_width, new_height);
	}

	/**
	 * 缩放图像（宽度缩放）
	 * 
	 * @param srcImageFile
	 *            源图像文件地址
	 * @param result
	 *            缩放后的图像地址
	 * @param height
	 *            缩放后的高度
	 * @param width
	 *            缩放后的宽度
	 * @param bb
	 *            比例不对时是否需要补白：true为补白; false为不补白;
	 */


    /**
     *
     * @param is
     * @param output
     * @param originalWidth
     */
	private void scaleByWidth(InputStream is, OutputStream output,
			int originalWidth) {
		try {

			double ratio = 0.0; // 缩放比例
			BufferedImage bi = ImageIO.read(is);
			if(bi == null){
				return;
			}

			Dimension dimension = getScaledDimension(
					new Dimension(bi.getWidth(), bi.getHeight()), originalWidth);

			Image itemp = bi.getScaledInstance(dimension.width,
					dimension.height, bi.SCALE_SMOOTH);
			// 计算比例
			if ((bi.getHeight() > dimension.height)
					|| (bi.getWidth() > dimension.width)) {
				if (bi.getHeight() > bi.getWidth()) {
					ratio = (new Integer(dimension.height)).doubleValue()
							/ bi.getHeight();
				} else {
					ratio = (new Integer(dimension.width)).doubleValue()
							/ bi.getWidth();
				}
				AffineTransformOp op = new AffineTransformOp(
						AffineTransform.getScaleInstance(ratio, ratio), null);
				itemp = op.filter(bi, null);
				ImageIO.write((BufferedImage) itemp, "PNG", output);
				return;
			}

			ImageIO.write(toBufferedImage(itemp), "PNG", output);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static BufferedImage toBufferedImage(Image img) {
		if (img instanceof BufferedImage) {
			return (BufferedImage) img;
		}

		// Create a buffered image with transparency
		BufferedImage bimage = new BufferedImage(img.getWidth(null),
				img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

		// Draw the image on to the buffered image
		Graphics2D bGr = bimage.createGraphics();
		bGr.drawImage(img, 0, 0, null);
		bGr.dispose();

		// Return the buffered image
		return bimage;
	}

}
